package com.gxg.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 实现Java对HDFS的文件操作
 * 1. 上传文件
 * 2. 下载文件
 * 3. 删除文件
 */
public class HdfsOp {

    public static void main(String[] args) throws Exception {
        //创建配置对象
        Configuration conf = new Configuration();
        //指定HDFS的地址：能写主机名的前提是host文件中配置了主机名与IP的映射关系
        conf.set("fs.defaultFS", "hdfs://bigdata01:9000");
        //获取操作HDFS的对象：FileSystem
        FileSystem fileSystem = FileSystem.get(conf);

        //1. 上传本地文件到HDFS
        upload(fileSystem);

        //2. 下载HDFS文件到本地
        download(fileSystem);

        //3. 删除HDFS中的文件或目录
        delete(fileSystem);
    }

    /**
     * 删除HDFS中的文件或目录
     * @param fileSystem
     * @throws IOException
     */
    private static void delete(FileSystem fileSystem) throws IOException {
        // 如果要递归删除目录，则第二个参数需设置为true
        // 如果删除的是文件或空目录，则第二个参数被忽略
        boolean flag = fileSystem.delete(new Path("/LICENSE.txt"), true);
        if(flag){
            System.out.println("删除成功！");
        }else {
            System.out.println("删除失败！");
        }
    }

    /**
     * 下载HDFS文件到本地
     * @param fileSystem 操作HDFS的对象
     * @throws IOException
     */
    private static void download(FileSystem fileSystem) throws IOException {
        //获取HDFS文件系统中的输入流
        FSDataInputStream fis = fileSystem.open(new Path("/README.txt"));
        //获取本地文件的输出流
        FileOutputStream fos = new FileOutputStream("C:\\tmp\\README.txt");
        //把HDFS的输入流复制到本地文件的输出流, 实现文件下载功能
        IOUtils.copyBytes(fis, fos, 1024, true);
    }

    /**
     * 上传本地文件到HDFS
     * @param fileSystem  操作HDFS的对象
     * @throws IOException
     */
    private static void upload(FileSystem fileSystem) throws IOException {
        //获取本地文件的输入流
        FileInputStream fis = new FileInputStream("C:\\tmp\\test.txt");
        //获取HDFS文件系统的输出流，即指定上传到HDFS后产生的文件名及其绝对路径
        FSDataOutputStream fos = fileSystem.create(new Path("/test_upload.txt"));
        //把本地文件的输入流复制到HDFS的输出流, 实现文件上传功能
        IOUtils.copyBytes(fis, fos, 1024L, true);
    }

}
